

import 'package:tencent_rtc/bindings/trtc_cloud_listener_native.dart';
import 'package:tencent_rtc/bindings/tx_audio_effect_manager_native.dart';
import 'package:tencent_rtc/bindings/tx_device_manager_native.dart';
import 'package:tencent_rtc/tx_audio_effect_manager.dart';

class TXAudioEffectManagerImpl extends TXAudioEffectManager {
  final String _tag = 'TXAudioEffectManagerImpl';
  late final TXAudioEffectManagerNative _audioEffectManagerNative;
  static TXAudioEffectManagerImpl? _instance;

  TXMusicPlayObserverNative? _musicPlayObserverNative;
  TXMusicPreloadObserverNative? _preloadObserverNative;

  TXAudioEffectManagerImpl._internal(dynamic audioEffectManagerFFIPointer) {
    _audioEffectManagerNative = TXAudioEffectManagerNative(audioEffectManagerFFIPointer);
  }

  factory TXAudioEffectManagerImpl(dynamic audioEffectManagerFFIPointer) {
    return _instance ??= TXAudioEffectManagerImpl._internal(audioEffectManagerFFIPointer);
  }

  static destroyAudioEffectManager() {
    _instance?._destroy();
    _instance = null;
  }

  _destroy() {
    _musicPlayObserverNative?.unRegisterNativeListener();
    _musicPlayObserverNative = null;

    _preloadObserverNative?.unRegisterNativeListener();
    _preloadObserverNative = null;
  }

  @override
  void enableVoiceEarMonitor(bool enable) {
    _audioEffectManagerNative.enableVoiceEarMonitor(enable);
  }

  @override
  int getMusicCurrentPosInMS(int id) {
    return _audioEffectManagerNative.getMusicCurrentPosInMS(id);
  }

  @override
  int getMusicDurationInMS(String path) {
    return _audioEffectManagerNative.getMusicDurationInMS(path);
  }

  @override
  int getMusicTrackCount(int id) {
    return _audioEffectManagerNative.getMusicTrackCount(id);
  }

  @override
  void pausePlayMusic(int id) {
    _audioEffectManagerNative.pausePlayMusic(id);
  }

  @override
  void preloadMusic(AudioMusicParam musicParam) {
    _audioEffectManagerNative.preloadMusic(musicParam);
  }

  @override
  void resumePlayMusic(int id) {
    _audioEffectManagerNative.resumePlayMusic(id);
  }

  @override
  void seekMusicToPosInTime(int id, int pts) {
    _audioEffectManagerNative.seekMusicToPosInTime(id, pts);
  }

  @override
  void setAllMusicVolume(int volume) {
    _audioEffectManagerNative.setAllMusicVolume(volume);
  }

  @override
  void setMusicObserver(int musicId, TXMusicPlayObserver? observer) {
    if (observer != null) {
      _musicPlayObserverNative ??= TXMusicPlayObserverNative(_audioEffectManagerNative.getNativePointer());
      _musicPlayObserverNative?.addMusicObserver(musicId, observer);
    } else {
      _musicPlayObserverNative?.removeMusicObserver(musicId);
    }
  }

  @override
  void setMusicPitch(int id, double pitch) {
    _audioEffectManagerNative.setMusicPitch(id, pitch);
  }

  @override
  void setMusicPlayoutVolume(int id, int volume) {
    _audioEffectManagerNative.setMusicPlayoutVolume(id, volume);
  }

  @override
  void setMusicPublishVolume(int id, int volume) {
    _audioEffectManagerNative.setMusicPublishVolume(id, volume);
  }

  @override
  void setMusicScratchSpeedRate(int id, double scratchSpeedRate) {
    _audioEffectManagerNative.setMusicScratchSpeedRate(id, scratchSpeedRate);
  }

  @override
  void setMusicSpeedRate(int id, double rate) {
    _audioEffectManagerNative.setMusicSpeedRate(id, rate);
  }

  @override
  void setMusicTrack(int id, int trackIndex) {
    _audioEffectManagerNative.setMusicTrack(id, trackIndex);
  }

  @override
  void setPreloadObserver(TXMusicPreloadObserver? observer) {
    if (observer != null) {
      _preloadObserverNative ??= TXMusicPreloadObserverNative(_audioEffectManagerNative.getNativePointer());
      _preloadObserverNative?.addListener(observer);
    } else {
      _preloadObserverNative?.clearListeners();
    }
  }

  @override
  void setVoiceCaptureVolume(int volume) {
    _audioEffectManagerNative.setVoiceCaptureVolume(volume);
  }

  @override
  void setVoiceChangerType(TXVoiceChangerType type) {
    _audioEffectManagerNative.setVoiceChangerType(type);
  }

  @override
  void setVoiceEarMonitorVolume(int volume) {
    _audioEffectManagerNative.setVoiceEarMonitorVolume(volume);
  }

  @override
  void setVoicePitch(double pitch) {
    _audioEffectManagerNative.setVoicePitch(pitch);
  }

  @override
  void setVoiceReverbType(TXVoiceReverbType type) {
    _audioEffectManagerNative.setVoiceReverbType(type);
  }

  @override
  void startPlayMusic(AudioMusicParam musicParam) {
    _audioEffectManagerNative.startPlayMusic(musicParam);
  }

  @override
  void stopPlayMusic(int id) {
    _audioEffectManagerNative.stopPlayMusic(id);
  }

}